package fournitures;

import fournitures.Channel;
import fournitures.ConnectionRefusedException;
import fournitures.ConnectionTimeoutException;
import fournitures.FatalChannelException;
import fournitures.Port;

public class ErrorChannel extends Channel {

	static double epsilon=0.111426;	// must be the same for all error channels
	
	public ErrorChannel(String address, int portNumber, int timeout,
			boolean displayDebuggingMessages, String name)
			throws ConnectionTimeoutException, ConnectionRefusedException,
			FatalChannelException {
		super(address, portNumber, timeout, displayDebuggingMessages, name);
		// TODO Auto-generated constructor stub
	}

	public ErrorChannel(Port port, boolean displayDebuggingMessages, String name)
			throws FatalChannelException {
		super(port, displayDebuggingMessages, name);
		// TODO Auto-generated constructor stub
	}
    
	public Packet receivePacket () throws FatalChannelException {
        // Analogous to receiveString but for objects of type Packet.

  
        // This method implements random loss of packets in the
        // channel. A random value between 0 and 1 is generated. If
        // that value is less than epsilon, then the packet is lost.
        // Losing a packet is implemented by returning null
       
        Packet packet = null;
        if (displayDebuggingMessages) {
            System.out.println("     Channel " + name1 + "/" + name2 + 
                               ": waiting for a packet ...");
        }
        try {
            packet = (Packet)(in.readObject()); 
            if (packet != null) {
                if (displayDebuggingMessages) {
                    System.out.println("     Channel " + name1 + "/" + name2 + 
                                       ": received packet " + packet);
                }
            }
           
            // Check if this packet should be lost. 
           
            
            
            if (packet != null) {
                double r = Math.random();
                if (r < epsilon) {
                    if (displayDebuggingMessages) {
                        System.out.println("     Channel " + name1 + "/" + name2 + 
                                           ": oops, that packet was unfortunately lost.");
                    }
                    // Wait for another packet with a recursive call:
                   // packet = receivePacket(); //-> takes too much time
                    packet=null;
                }
            }
        }
        catch (java.net.SocketTimeoutException e){
        	FatalChannelException ce = new FatalChannelException(e);
        	throw(ce);
        }
        catch (java.io.IOException e) {
            System.out.println("Channel: an error occurred while waiting for a message.");
            e.printStackTrace();
            FatalChannelException ce = new FatalChannelException(e);
            throw(ce);
        } 
        catch (ClassNotFoundException e) {
            System.out.println("Channel: an error occurred while waiting for a message.");
            e.printStackTrace();
            FatalChannelException ce = new FatalChannelException(e);
            throw(ce);
        }
        return packet;
    }
	public static double getEpsilon(){
		
		return epsilon;
	}
}
